(*
	configureSPort keyword,keyword, ... Ñ Set the configuration of the port, as specified by a
		keyword list. The following keywords are allowed:

				modemPort/port1 - Use the modem port.
				printerPort/port2 - Use the printer port.
				baud300/baud600/baud1200/baud1800/baud2400/baud3600/
				baud4800/baud7200/baud9600/baud19200/baud57600 - Set the baud rate.
				stop10/stop15/stop20 - Set the number of stop bits to 1.0, 1.5, or 2.0.
				parityOff/parityOdd/parityEven - Set the parity.
				data5/data6/data7/data8 - Set the number of data bits.
				XOnOutOn/XOnOutOff - Enable or disable character flow control out outgoing data.
				CTSOutOn/CTSOutOff - Enable or disable signal flow control on outgoing data.
				linefeedOn/linefeedOff - Enable or disable sending of linefeeds after each carriage return.
				echoOn/echoOff - Enable or disable echoing of the input back to the output.
				editOn/editOff - Enable or disable editing of the input from the input (i.e., backspaces).
				stripOn/stripOff - Enable or disable striping of the top bit of the input.
				stripControlsOn/stripControlsOff - Enable or disable striping of control characters (except return and tab).
				autoWrapOn/autoWrapOff - Enable or disable automatic wrapping of input and output.

	To compile and link this file using Macintosh Programmer's Workshop,

		pascal -w configureSPort.p
		link -m ENTRYPOINT -o HyperCommands -rt XCMD=7035 -sn Main=configureSPort ¶
			configureSPort.p.o "{MPW}"Libraries:interface.o

	© Copyright 1987,88 by Apple Computer, Inc.

	Initial coding 9/87 by Harry R. Chesley.
*)

{$R-}

{$S configureSPort } 	{ Segment name must be the same as the command name. }

unit DummyUnit;

interface

uses MemTypes, QuickDraw, OSIntf, ToolIntf, HyperXCmd;

procedure EntryPoint(paramPtr: XCmdPtr);
	
implementation

type

Str31 = String[31];

procedure configureSPort(paramPtr: XCmdPtr); forward;

procedure EntryPoint(paramPtr: XCmdPtr);

	begin
		configureSPort(paramPtr);
	end;

procedure configureSPort(paramPtr: XCmdPtr);

	var i: integer;
		parmStr: str255;
		hasChanged: boolean;

	{$I XCmdGlue.inc}

	procedure Fail(errMsg: Str255); { set theResult and quit }
		begin
			paramPtr^.returnValue := PasToZero(errMsg);
			exit(configureSPort);
		end;

	{$I SPortUtil.inc}

	procedure changeByte(mask, value: longInt);

		begin
			ThisSPort.byteConfig := BitOr(BitAnd(BitNot(mask),ThisSPort.byteConfig),value);
		end;

	procedure updateIfChanged;
		{ If there have been any changes in the configuration, set the port. }

		begin
			if hasChanged then
				begin
					{ Save the settings. }
					Globals^^.ports[Globals^^.selectedPort] := ThisSPort;
			
					{ Open it if it hasn't already been opened. }
					EnsureOpenPort;
					{ Set the port. }
					with ThisSPort do
						begin
							if SerHShake(portInDev,shakes) <> noErr then Fail('SerHShake failed');
							if SerHShake(portOutDev,shakes) <> noErr then Fail('SerHShake failed');
							if (SerReset(portInDev,byteConfig) <> noErr) or
									(SerReset(portOutDev,byteConfig) <> noErr) then
								Fail('SerReset failed');
						end;
					hasChanged := false;
				end;
		end;

	procedure selectPort(whichPort: SPortSel);
		{ Switch to a new port. }

		begin
			updateIfChanged;
			Globals^^.selectedPort := whichPort;
			ThisSPort := Globals^^.ports[whichPort];
		end;

	begin
		if paramPtr^.paramCount = 0 then Fail('no parameters');

		SetUpSPortGlobals;

		{ Go through the configuration parameters, one by one...}
		hasChanged := false;
		with ThisSPort do
			for i := 1 to paramPtr^.paramCount do
				begin
					GetStrParm(i,parmStr);
					if StringEqual(parmStr,'modemPort') or StringEqual(parmStr,'port1') then
						begin
							selectPort(sPortA);
							cycle;
						end
					else if StringEqual(parmStr,'printerPort') or StringEqual(parmStr,'port2') then
						begin
							selectPort(sPortB);
							cycle;
						end
					else if StringEqual(parmStr,'baud300') then changeByte($003FF,baud300)
					else if StringEqual(parmStr,'baud600') then changeByte($003FF,baud600)
					else if StringEqual(parmStr,'baud1200') then changeByte($003FF,baud1200)
					else if StringEqual(parmStr,'baud1800') then changeByte($003FF,baud1800)
					else if StringEqual(parmStr,'baud2400') then changeByte($003FF,baud2400)
					else if StringEqual(parmStr,'baud3600') then changeByte($003FF,baud3600)
					else if StringEqual(parmStr,'baud4800') then changeByte($003FF,baud4800)
					else if StringEqual(parmStr,'baud7200') then changeByte($003FF,baud7200)
					else if StringEqual(parmStr,'baud9600') then changeByte($003FF,baud9600)
					else if StringEqual(parmStr,'baud19200') then changeByte($003FF,baud19200)
					else if StringEqual(parmStr,'baud57600') then changeByte($003FF,baud57600)
					else if StringEqual(parmStr,'stop10') then changeByte($0C000,stop10)
					else if StringEqual(parmStr,'stop15') then changeByte($0C000,stop15)
					else if StringEqual(parmStr,'stop20') then changeByte($0C000,stop20)
					else if StringEqual(parmStr,'parityOff') then changeByte($03000,noParity)
					else if StringEqual(parmStr,'parityOdd') then changeByte($03000,oddParity)
					else if StringEqual(parmStr,'parityEven') then changeByte($03000,evenParity)
					else if StringEqual(parmStr,'data5') then changeByte($00C00,data5)
					else if StringEqual(parmStr,'data6') then changeByte($00C00,data6)
					else if StringEqual(parmStr,'data7') then changeByte($00C00,data7)
					else if StringEqual(parmStr,'data8') then changeByte($00C00,data8)
					else if StringEqual(parmStr,'XOnOutOn') then shakes.fXOn := 1
					else if StringEqual(parmStr,'XOnOutOff') then shakes.fXOn := 0
					else if StringEqual(parmStr,'CTSOutOn') then shakes.fCTS := 1
					else if StringEqual(parmStr,'CTSOutOff') then shakes.fCTS := 0
					else if StringEqual(parmStr,'linefeedOn') then sendLFs := true
					else if StringEqual(parmStr,'linefeedOff') then sendLFs := false
					else if StringEqual(parmStr,'echoOn') then doEcho := true
					else if StringEqual(parmStr,'echoOff') then doEcho := false
					else if StringEqual(parmStr,'editOn') then doEdit := true
					else if StringEqual(parmStr,'editOff') then doEdit := false
					else if StringEqual(parmStr,'stripOn') then stripIncoming := true
					else if StringEqual(parmStr,'stripOff') then stripIncoming := false
					else if StringEqual(parmStr,'stripControlsOn') then stripControls := true
					else if StringEqual(parmStr,'stripControlsOff') then stripControls := false
					else if StringEqual(parmStr,'autoWrapOn') then autoWrap := true
					else if StringEqual(parmStr,'autoWrapOff') then autoWrap := false;
					hasChanged := true;
				end;

		{ Set it if it's been changed. }
		updateIfChanged;
		{ And make sure the current port is open, even if we didn't change anything. }
		EnsureOpenPort;
	end;

end.
